#pragma once

#include <cassert>
#include <cstring>
#include <iostream>
using namespace std;

namespace str
{
	class String
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;

		String(const char* str = "");

		String(const String& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			String tmp(s._str);
			swap(tmp);
		}

		~String();

		str::String::iterator begin();
		str::String::iterator end();
		str::String::const_iterator begin() const;
		str::String::const_iterator end() const;

		char& operator[](size_t pos);
		const char& operator[](size_t pos) const;
		
		size_t size() const;
		size_t capacity() const;
		const char* c_str() const;

		void clear();
		void reserve(size_t n);
		void push_back(char n);
		void append(const char* str);
		void insert(size_t pos, char ch);
		void insert(size_t pos, char* str);
		
		//void resize(size_t n, char ch = '\0');
		//size_t find(char ch, size_t pos = 0);
		//string substr(size_t pos, size_t len = npos);
		//size_t find(const char* sub, size_t pos = 0);

		void swap(String& s);

		String& operator=(String tmp);
		bool operator<(const String& s) const;
		bool operator<=(const String& s) const;
		bool operator!=(const String& s) const;
		bool operator==(const String& s) const;
		bool operator>(const String& s) const;
		bool operator>=(const String& s) const;
		String& operator+=(const char* s);
		String& operator+=(char ch);

	private:
		char* _str;
		size_t _size;
		size_t _capacity;

	public:
		const static size_t npos = -1;
	};
	/*const size_t String::npos = -1;*/

	ostream& operator<<(ostream& out, const String& s);
}